//
//  MMMainViewController.m
//  MemeEditor
//
//  Created by Phan Quang Ha on 7/4/13.
//  Copyright (c) 2013 soyo. All rights reserved.
//

#import "MMMainViewController.h"
#import "MMMovableImage.h"
#import "MMMovableText.h"
#import "MMMenuView.h"
#import "MMTextPreviewViewController.h"
#import "MMActionView.h"
#import "MMCameraAndImagePickerViewController.h"

#import "MMConstants.h"
#import "MMRightActionView.h"

#import "MMUndoManager.h"

#import "UITableViewCell+LoadFromNib.h"
#import "UIBarButtonItem+Custom.h"
#import <Social/Social.h>

#import "UIImage+Util.h"

#define kMoveableImageTag 14
#define kMoveableTextTag 15

@interface MMMainViewController ()
{
    MMMenuView *menuView;
    MMPenStyleViewController *penStyleController;
    MMTextStyleViewController *textStyleController;
    MMScrollPreviewView *scrollPreview;
    MMTextPreviewViewController *textPreviewController;
    MMActionView *topActionView;
    MMRightActionView *rightActionView;
    
    MMMovableImage *movingImage;
    MMMovableText *movingText;

    UIButton *btnShowPreview;
    
    BOOL isShowingPreview;
    BOOL isAddingViews;
    DRAWING_STATE state;
    
    MMUndoManager *undoManager;
    
    UIBarButtonItem *btnCancel;
    UIBarButtonItem *btnApply;
    
    UIBarButtonItem *barBtnSave;
    
    BOOL isEdit;
    BOOL firstLoad;
}

- (void) share:(BOOL) type;
- (void) saveToGallery;

@end

@implementation MMMainViewController
@synthesize paintingView;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        undoManager = [[MMUndoManager alloc] init];
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    firstLoad = YES;
    self.title = APP_NAME;
    isEdit = NO;
    state = sDrawing;
    
    [self generateTopAction];
    [barBtnSave setEnabled:NO];

}
- (void) generateTopAction
{
    if (state == sDrawing) {
        UIBarButtonItem *barBtnCancel;
        barBtnCancel = [UIBarButtonItem barItemWithImage:[UIImage imageNamed:@"ico_prev.png"] size:CGSizeMake(35, 35) target:self action:@selector(cancelDrawingImage)];
        [self.navigationItem setLeftBarButtonItem:barBtnCancel animated:YES];
        
        barBtnSave = [UIBarButtonItem barItemWithImage:[UIImage imageNamed:@"ico_action.png"] size:CGSizeMake(35, 35) target:self action:@selector(needSaveCurrentImage)];
        [self.navigationItem setRightBarButtonItem:barBtnSave animated:YES];
    }else{
        if (!btnCancel) {
            btnCancel = [UIBarButtonItem barItemWithImage:[UIImage imageNamed:@"ico_cancel.png"] size:CGSizeMake(35, 35) target:self action:@selector(cancelAdding:)];
        }
        [self.navigationItem setLeftBarButtonItem:btnCancel animated:YES];
        
        if (!btnApply) {
            btnApply = [UIBarButtonItem barItemWithImage:[UIImage imageNamed:@"ico_apply.png"] size:CGSizeMake(35, 35) target:self action:@selector(confirmAdding:)];
        }
        [self.navigationItem setRightBarButtonItem:btnApply animated:YES];
    }
}

- (void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    if (!paintingView) {
        paintingView = [[MMPaintingView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
        paintingView.dState = sDrawing;
        [self.view addSubview:paintingView];
        paintingView.backgroundColor = [UIColor whiteColor];
        paintingView.delegate = self;
        
        if (!self.needEditImage) {
            [undoManager addObjectToStack:[paintingView getFullImage]];
        }
        
    }
    if (!topActionView){
        topActionView = [[MMActionView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 35)];
        topActionView.hidden = YES;
        [topActionView.btnAction2 addTarget:self action:@selector(confirmAdding:) forControlEvents:UIControlEventTouchUpInside];
        [topActionView.btnAction1 addTarget:self action:@selector(cancelAdding:) forControlEvents:UIControlEventTouchUpInside];
        
        [self.view addSubview:topActionView];
    }
    
    if (!menuView) {
        menuView = [[MMMenuView alloc] initWithPosition:kBOT_RIGHT inFrame:self.view.bounds];
        [self.view addSubview:menuView];
        [menuView setMainImage:[UIImage imageNamed:@"ico_menu.png"]];
        [menuView set1stAction:@selector(showPenStyleController) target:self andImage:[UIImage imageNamed:@"ico_btn1"]];
        [menuView set2ndAction:@selector(showFontStyleController) target:self andImage:[UIImage imageNamed:@"ico_btn2"]];
        [menuView set3rdAction:@selector(showChoosePicker) target:self andImage:[UIImage imageNamed:@"ico_btn3"]];
    }
    if (!scrollPreview) {
        ///dang con bug, de chieu anh sua cho nay
        CGRect bigRect = paintingView.bounds;
        
        scrollPreview = [[MMScrollPreviewView alloc] initWithBigRect:bigRect smallRect:self.view.bounds andImage:[paintingView getFullImage]];
        scrollPreview.backgroundColor = [UIColor lightGrayColor];
        [self.view addSubview:scrollPreview];
        scrollPreview.delegate = self;
    }
    if (!btnShowPreview) {
        btnShowPreview = [[UIButton alloc] initWithFrame:CGRectMake(0, self.view.bounds.size.height/2 - 30, 20, 60)];
        [btnShowPreview setImage:[UIImage imageNamed:@"ico_show_preview"] forState:UIControlStateNormal];
        [btnShowPreview addTarget:self action:@selector(showPreview:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:btnShowPreview];
    }
    if (!rightActionView) {
        rightActionView = [UITableViewCell loadCellFromNibName:@"MMRightActionView"];
        
        [rightActionView.btnEraser addTarget:self action:@selector(beginErasing) forControlEvents:UIControlEventTouchUpInside];
        [rightActionView.btnPencil addTarget:self action:@selector(beginPainting) forControlEvents:UIControlEventTouchUpInside];
        [rightActionView.btnUndo addTarget:self action:@selector(undoPainting) forControlEvents:UIControlEventTouchUpInside];
        [rightActionView.btnRedo addTarget:self action:@selector(redoPainting) forControlEvents:UIControlEventTouchUpInside];
        
        CGRect frame = rightActionView.frame;
        rightActionView.frame = CGRectMake(self.view.bounds.size.width - frame.size.width, 0, frame.size.width, frame.size.height);
        [self.view addSubview:rightActionView];
    }
    if (firstLoad) {
        if (self.needEditImage) {
            [self.paintingView beginEditImage:_willEditImage];
            isEdit = NO;
            [barBtnSave setEnabled:NO];
            self.title = self.willEditName;
            
            [undoManager addObjectToStack:[paintingView getFullImage]];
        }else{
            self.willEditName = @"";
        }
        firstLoad = NO;
    }
    
}
- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

- (void) dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload {
    [super viewDidUnload];
}

#pragma mark - Adding components
- (void) showPenStyleController
{
    if (!penStyleController) {
        penStyleController = [[MMPenStyleViewController alloc] initWithNibName:@"MMPenStyleViewController" bundle:nil];
        penStyleController.delegate = self;
        penStyleController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    }
    
    [self presentViewController:penStyleController animated:YES completion:nil];
}
- (void) showFontStyleController
{
    [menuView bring2ndActionToFront];
    if (!textPreviewController) {
        textPreviewController = [[MMTextPreviewViewController alloc]  initWithNibName:@"MMTextPreviewViewController" bundle:nil];
        [textPreviewController setDelegate:self];
        textPreviewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    }
    if (state != sAddingText) {
        textPreviewController.txtPreview.text = @"";
    }
    [self presentViewController:textPreviewController animated:YES completion:nil];
}
- (void) showChoosePicker
{
    [menuView bring3rdActionToFront];
    
    UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:NSLocalizedString(@"cancel", @"") destructiveButtonTitle:NSLocalizedString(@"loadmeme", @"") otherButtonTitles:NSLocalizedString(@"Album gallery", @""), NSLocalizedString(@"takeashoot", @""), nil];
    [sheet showInView:self.view];
//    MMMemePickerViewController *picker = [[MMMemePickerViewController alloc] initWithNibName:@"MMMemePickerViewController" bundle:nil];
//    picker.delegate = self;
//    state = sAddingImage;
//    [self.navigationController pushViewController:picker animated:YES];
}
- (void) showPreview:(UIButton *)btn
{
    if (!isShowingPreview) {
        [UIView animateWithDuration:0.3 animations:^{
            CGRect sframe = scrollPreview.frame;
            sframe.origin.x = sframe.origin.x + sframe.size.width;
            scrollPreview.frame = sframe;
            
            CGRect bframe = btn.frame;
            bframe.origin.x = sframe.size.width - bframe.size.width;
            btn.frame = bframe;
            
            isShowingPreview = YES;
            [btn setImage:[UIImage imageNamed:@"ico_hide_preview"] forState:UIControlStateNormal];
        }];
        
    }else{
        [UIView animateWithDuration:0.3 animations:^{
            CGRect sframe = scrollPreview.frame;
            sframe.origin.x = sframe.origin.x - sframe.size.width;
            scrollPreview.frame = sframe;
            
            CGRect bframe = btn.frame;
            bframe.origin.x = 0;
            btn.frame = bframe;
            
            isShowingPreview = NO;
            [btn setImage:[UIImage imageNamed:@"ico_show_preview"] forState:UIControlStateNormal];
        }];
    }
}
//TOP RIGHT ACTION
- (void) undoPainting
{
    [paintingView drawLogImage:[undoManager undo]];
    rightActionView.btnUndo.enabled = [undoManager canUndo];
    rightActionView.btnRedo.enabled = [undoManager canRedo];
    
}
- (void) redoPainting
{
    [paintingView drawLogImage:[undoManager redo]];
    rightActionView.btnUndo.enabled = [undoManager canUndo];
    rightActionView.btnRedo.enabled = [undoManager canRedo];
}
- (void) beginPainting
{
    paintingView.isErasing = NO;
    rightActionView.btnEraser.selected = NO;
    rightActionView.btnPencil.selected = YES;
}
- (void) beginErasing
{
    paintingView.isErasing = YES;
    MMEraserViewController *eraser = [[MMEraserViewController alloc] initWithNibName:@"MMEraserViewController" bundle:nil];
    eraser.delegate = self;
    eraser.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    [self presentViewController:eraser animated:YES completion:nil];
    
    eraser.sliderSize.value = paintingView.eraserSize;
    [eraser didChangeSize:eraser.sliderSize];
}

//TOP ACTION when add a text/image
- (void) confirmAdding:(UIButton *)btn
{
    //set is current edit
    isEdit = YES;
    [barBtnSave setEnabled:YES];
    
    switch (state) {
        case sAddingImage:
        {
            [paintingView drawImage:movingImage.mImage atRect:movingImage.frame blendMode:kCGBlendModeNormal andAlpha:1.0f];
        }
            break;
        case sAddingText:
        {
            [paintingView drawText:movingText.mString atRect:movingText.frame withFont:movingText.mFont color:movingText.mTextColor andTextAlignment:movingText.mTextAlignment];
        }
            break;
        default:
            break;
    }
    [menuView bringMainActionToFront];
    paintingView.dState = sDrawing;
    state = sDrawing;
    movingImage.hidden = YES;
    movingText.hidden  = YES;
    
    [rightActionView performSelector:@selector(setHidden:) withObject:nil afterDelay:0.3f];
    [self generateTopAction];
}
- (void) cancelAdding:(UIButton *)btn
{
    [menuView bringMainActionToFront];
    paintingView.dState = sDrawing;
    [paintingView receivedMovingSubViewWithNotification:nil];
    state = sDrawing;
    movingImage.hidden = YES;
    movingText.hidden = YES;
    
    [rightActionView performSelector:@selector(setHidden:) withObject:nil afterDelay:0.3f];
    [self generateTopAction];
}
#pragma mark - Custom Delegate
- (void)didFinishChangingPen:(MMBasicPen *)pen
{
    paintingView.currentPen = pen;
    [self beginPainting];
}
- (void)didChangeOrigin:(CGFloat)y withRate:(CGFloat)rate
{
    CGRect paintingFrame = paintingView.frame;
    paintingFrame.origin.y = paintingFrame.origin.y - y*rate;
    paintingView.frame = paintingFrame;
}

- (void) didChangedParentHeight:(CGFloat)h withRate:(CGFloat)rate {
    CGRect paintingFrame = paintingView.frame;
    paintingFrame.origin.y += h*rate;
    paintingView.frame = paintingFrame;
}

- (void)didChangeWithImage:(UIImage *)img rect:(CGRect)rect isNotification:(BOOL)isNotify
{
    //set is current edit    
    isEdit = YES;
    [barBtnSave setEnabled:YES];

    [scrollPreview setBigRect:rect andImage:img];
    if (!isNotify) {
        [undoManager addObjectToStack:img];
        rightActionView.btnUndo.enabled = [undoManager canUndo];
        rightActionView.btnRedo.enabled = [undoManager canRedo];
    }
    
}

- (void) changedWithHeight:(CGFloat)h {
    [paintingView increaseHeight:h];
}

- (void)didSelectImage:(UIImage *)img
{
    if (img) {
        if (!movingImage) {
            movingImage = [[MMMovableImage alloc] initWithImage:img];
            [paintingView addSubview:movingImage];
            movingImage.hidden = YES;
            paintingView.movingImage = movingImage;
        }
        
        paintingView.dState = sAddingImage;
        
        [movingImage setMImage:img];
        
        if (movingImage.hidden) {
            CGRect frame = movingImage.frame;
            frame.origin.y = frame.origin.y - paintingView.frame.origin.y;
            movingImage.frame = frame;
            
            
            [self performSelector:@selector(generateTopAction) withObject:nil afterDelay:0.2];
            [rightActionView performSelector:@selector(setHidden:) withObject:@YES afterDelay:0.5f];
//            [topActionView performSelector:@selector(setHidden:) withObject:nil afterDelay:1.0f];
            
        }
        movingImage.hidden = NO;
        
        [paintingView receivedMovingSubViewWithNotification:nil];
    }else{
        [menuView bringMainActionToFront];
    }
    
}

- (void) didApplyWithString:(NSString *)mText color:(UIColor *)mColor font:(UIFont *)mFont andAlign:(NSTextAlignment)mAlign {
    if (mText) {
        if (!movingText) {
            movingText = [[MMMovableText alloc] initWithText:mText font:mFont textAlignment:mAlign andTextColor:mColor];
            [paintingView addSubview:movingText];
            movingText.hidden = YES;
            paintingView.movingText = movingText;
        }
        state = sAddingText;
        paintingView.dState = sAddingText;
        
        [movingText setMString:mText];
        [movingText setMFont:mFont];
        [movingText setMTextColor:mColor];
        [movingText setMTextAlignment:mAlign];
        
        if (movingText.hidden) {
            CGRect frame = movingText.frame;
            frame.origin.y = self.view.frame.origin.y - paintingView.frame.origin.y + 30;
            movingText.frame = frame;
            
            [self performSelector:@selector(generateTopAction) withObject:nil afterDelay:0.2];
            [rightActionView performSelector:@selector(setHidden:) withObject:@YES afterDelay:0.5f];
//            [topActionView performSelector:@selector(setHidden:) withObject:nil afterDelay:1.0f];

        }
        
        movingText.hidden = NO;
        
        [paintingView receivedMovingSubViewWithNotification:nil];
    }else{
        [menuView bringMainActionToFront];
    }
}

- (void)didSelectSize:(CGFloat)size
{
    paintingView.eraserSize = size;
}

//Cancel/Save current Image
- (void)needSaveCurrentImage
{
    
    UIAlertView *alrShare = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"option", @"") message:NSLocalizedString(@"confirm_share", @"") delegate:self cancelButtonTitle:NSLocalizedString(@"cancel", @"") otherButtonTitles:NSLocalizedString(@"savetoworkspace", @""), NSLocalizedString(@"savegallery", @""), NSLocalizedString(@"facebook", @""), NSLocalizedString(@"twitter", @""), nil];
    alrShare.tag = ALERT_TAG_CONFIRM_SHARE;
    [alrShare show];
    
    
    
}
- (void)cancelDrawingImage
{
    if (isEdit) {
        isEdit = NO;
        UIAlertView *al = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"drawing", @"") message:NSLocalizedString(@"confirmcanceldrawing", @"") delegate:self cancelButtonTitle:NSLocalizedString(@"cancel", @"") otherButtonTitles:NSLocalizedString(@"ok", @""), nil];
        al.tag = ALERT_TAG_CONFIRM_CANCEL;
        [al show];
    } else {
        scrollPreview.hidden = YES;
        [self.navigationController popViewControllerAnimated:YES];
    }
    
}
#pragma mark - UIAlertView
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    switch (alertView.tag) {
        case ALERT_TAG_CONFIRM_CANCEL:
            if (buttonIndex == 1) {
                scrollPreview.hidden = YES;
                [self.navigationController popViewControllerAnimated:YES];
            } else {
                isEdit = YES;
            }
            break;
        case ALERT_TAG_CONFIRM_SAVE:
            if (buttonIndex == 1) {
                BOOL saved = [self saveToWorkSpaceWithName:[alertView textFieldAtIndex:0].text];
                if (saved) {
                    scrollPreview.hidden = YES;
                    [self.navigationController popToRootViewControllerAnimated:YES];
                }
            }
            break;
        case ALERT_TAG_CONFIRM_SHARE: {
            if (buttonIndex == 1) {
                UIAlertView *al = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"drawing", @"") message:NSLocalizedString(@"confirmsavedrawing", @"") delegate:self cancelButtonTitle:NSLocalizedString(@"cancel", @"") otherButtonTitles:NSLocalizedString(@"save", @""), nil];
                al.alertViewStyle = UIAlertViewStylePlainTextInput;
                al.tag = ALERT_TAG_CONFIRM_SAVE;
                [al show];
                UITextField *txt = [al textFieldAtIndex:0];
                txt.text = self.willEditName;
            } else if (buttonIndex == 2) { //save to gallery
                [self saveToGallery];
            } else if (buttonIndex == 3) { //Facebook
                [self share:YES];
            } else if (buttonIndex == 4) { //Twitter
                [self share:NO];
            } else {
//                [self.navigationController popViewControllerAnimated:YES];
            }
            break;
        }
            
        default:
            break;
    }
}
#pragma mark - Utility Methods
// Top action save to workspace
- (BOOL) saveToWorkSpaceWithName:(NSString *)name
{
    NSString *pathToSave = [[[DOCUMENT_FOLDER stringByAppendingPathComponent:FOLDER_WORKSPACE] stringByAppendingPathComponent:name] stringByAppendingPathExtension:@"png"];
    [[NSFileManager defaultManager] createDirectoryAtPath:[pathToSave stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:nil];
    
    NSData *binaryImage = UIImagePNGRepresentation([paintingView getFullImage]);
    if ([[NSFileManager defaultManager] fileExistsAtPath:pathToSave]) {
        if (self.needEditImage) {
            [[NSFileManager defaultManager] removeItemAtPath:pathToSave error:nil];
        }else{
            UIAlertView *al = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"drawing", @"") message:NSLocalizedString(@"duplicatedname", @"") delegate:nil cancelButtonTitle:NSLocalizedString(@"ok", nil) otherButtonTitles:nil, nil];
            [al show];
            return NO;
        }
        
    }
    BOOL success = [binaryImage writeToFile:pathToSave atomically:YES];
    return success;
}

#pragma mark - Share method
- (void) share:(BOOL) type {
    SLComposeViewController *slShare;
    if (type == YES) {
        slShare = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
    } else {
        slShare = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
    }
    
    slShare.completionHandler = ^(SLComposeViewControllerResult result){
        switch (result) {
            case SLComposeViewControllerResultCancelled:
                NSLog(@"cancel");
                break;
            case SLComposeViewControllerResultDone:
                NSLog(@"Post");
                break;
            default:
                break;
        }
        //dismiss
        dispatch_async(dispatch_get_main_queue(), ^{
            [self dismissViewControllerAnimated:NO completion:^{
                NSLog(@"dissmiss.");
            }];
        });
    };
    [slShare setInitialText:APP_NAME];
    [slShare addImage:[paintingView getFullImage]];
    [slShare addURL:[NSURL URLWithString:APP_LINK]];
    [self presentViewController:slShare animated:YES completion:^(void){
        NSLog(@"presented");
    }];
}

- (void) saveToGallery
{
    UIImageWriteToSavedPhotosAlbum([paintingView getFullImage], nil, nil, nil);
}

#pragma mark = Actionsheet delegate
- (void) actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
    switch (buttonIndex) {
        case 0: {
            MMMemePickerViewController *picker = [[MMMemePickerViewController alloc] initWithNibName:@"MMMemePickerViewController" bundle:nil];
            picker.delegate = self;
            state = sAddingImage;
            [self.navigationController pushViewController:picker animated:YES];
        }
            break;
            
        case 1: {
            UIImagePickerController   *imagePickerController = [[UIImagePickerController alloc] init];
            imagePickerController.delegate = self;
            imagePickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;//UIImagePickerControllerSourceTypeSavedPhotosAlbum; //
            imagePickerController.allowsEditing = NO;
            state = sAddingImage;
            [self presentViewController:imagePickerController animated:YES completion:nil];

        }

            break;
            
        case 2: {
            MMCameraAndImagePickerViewController *cameraVC = [[MMCameraAndImagePickerViewController alloc] initWithNibName:@"MMCameraAndImagePickerViewController" bundle:nil];
            [cameraVC setDelegate:self];
            [cameraVC setHidesBottomBarWhenPushed:YES];
            state = sAddingImage;
            [self.navigationController pushViewController:cameraVC animated:YES];
        }
            break;
            
        default:
        {
            [menuView bringMainActionToFront];
        }
            break;
    }
}

#pragma mark - Camera delegate
- (void) didReceivedImage:(UIImage *)img {
    if (img) {
        [self didSelectImage:img];
    }
}

#pragma mark - UIPicker Delegate
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    UIImage *oriImage = [info valueForKey:UIImagePickerControllerOriginalImage];
    NSLog(@"imge with: %f and image height: %f", oriImage.size.width, oriImage.size.height);
    
    UIImage *resizedImage = [oriImage resizedImageNonCrop:CGSizeMake(oriImage.size.width/3, oriImage.size.height/3)];
    
    [self dismissViewControllerAnimated:YES completion:nil];
    [self didSelectImage:resizedImage];

}

- (void) imagePickerControllerDidCancel:(UIImagePickerController *)picker {
    [self dismissViewControllerAnimated:YES completion:nil];
}

@end
